package de.westranger.forex.code.script;																	// REMOVEME
																											// REMOVEME
																											// REMOVEME
public class MQLScriptPrototypeMA {																			// REMOVEME
																											// REMOVEME
	public static void initScript(){																		// REMOVEME
		arrayData = new double[INDICATOR_TOTAL][MAX_ARRAY_LEN];												// REMOVEME
	}																										// REMOVEME
	public static int sellCount = 0;																		// REMOVEME
	public static int buyCount = 0;																			// REMOVEME
	public static int FILE_CSV = 0;																			// REMOVEME
	public static int FILE_WRITE = 0;																		// REMOVEME
	public static int FILE_READ = 0;																		// REMOVEME
	public static int SEEK_END = 0;																			// REMOVEME
	public static int Green = 0;																			// REMOVEME
	public static int OP_BUY = 0;																			// REMOVEME
	public static int OP_SELL = 0;																			// REMOVEME
	public static int SELECT_BY_TICKET = 0;																	// REMOVEME
																											// REMOVEME
//#####################################################################################################		   REMOVEME
//###  here starts the script remove everthing above #################################################		   REMOVEME
//#####################################################################################################		   REMOVEME
																											// REMOVEME
	public static int INDICATOR_HIGH = 0;
	public static int INDICATOR_LOW = 1;
	public static int INDICATOR_ASK = 2;
	public static int INDICATOR_BID = 3;
	public static int INDICATOR_OPEN = 4;
	public static int INDICATOR_CLOSE = 5;
	public static int INDICATOR_TIME = 6;
	public static int INDICATOR_EMA3 = 7;
	public static int INDICATOR_EMA6 = 8;
	public static int INDICATOR_EMA9 = 9;
	public static int INDICATOR_EMA12 = 10;
	public static int INDICATOR_EMA15 = 11;
	public static int INDICATOR_EMA18 = 12;
	public static int INDICATOR_EMA21 = 13;
	public static int INDICATOR_EMA24 = 14;
	public static int INDICATOR_EMA27 = 15;
	public static int INDICATOR_EMA30 = 16;
	public static int INDICATOR_EMA33 = 17;
	public static int INDICATOR_EMA36 = 18;
	public static int INDICATOR_EMA39 = 19;
	public static int INDICATOR_EMA42 = 20;
	public static int INDICATOR_EMA45 = 21;
	public static int INDICATOR_EMA48 = 22;
	public static int INDICATOR_EMA51 = 23;
	public static int INDICATOR_EMA54 = 24;
	public static int INDICATOR_EMA57 = 25;
	public static int INDICATOR_EMA60 = 26;
	public static int INDICATOR_SMA3 = 27;
	public static int INDICATOR_SMA6 = 28;
	public static int INDICATOR_SMA9 = 29;
	public static int INDICATOR_SMA12 = 30;
	public static int INDICATOR_SMA15 = 31;
	public static int INDICATOR_SMA18 = 32;
	public static int INDICATOR_SMA21 = 33;
	public static int INDICATOR_SMA24 = 34;
	public static int INDICATOR_SMA27 = 35;
	public static int INDICATOR_SMA30 = 36;
	public static int INDICATOR_SMA33 = 37;
	public static int INDICATOR_SMA36 = 38;
	public static int INDICATOR_SMA39 = 39;
	public static int INDICATOR_SMA42 = 40;
	public static int INDICATOR_SMA45 = 41;
	public static int INDICATOR_SMA48 = 42;
	public static int INDICATOR_SMA51 = 43;
	public static int INDICATOR_SMA54 = 44;
	public static int INDICATOR_SMA57 = 45;
	public static int INDICATOR_SMA60 = 46;
	
	public static int INDICATOR_HL_AVG = 47;
	public static int INDICATOR_TOTAL = 48;
		
	public static int ACTIVE_SIGNAL_NONE = 0;
	public static int ACTIVE_SIGNAL_BUY = 1;
	public static int ACTIVE_SIGNAL_SELL = 2;

	// mql code
	// double arrayData[18][22]
	public static int MAX_ARRAY_LEN = 100;
	public static double[][] arrayData;
	public static int i;

	public static int signalType = 0;
	public static int signalTypePrev = 0;
	
	public static int globalIterationCounter;
	public static boolean execTestCase = false;
	public static boolean writeOutputFiles = true;
	
	// OANADA uses mini lots
	public static double LOT = 10000.0;
	public static int type = 0;
	public static int typePrev = 0;
	public static int ticket = -1;

	public static double stopLoss = 0.0174;
	public static double takeProfit = 0.0101;
	public static double invest;

	public static String outputFileIndicator = "mql_validation_mql_indicator.csv";
	public static String outputFileLogic = "mql_validation_mql_logic.csv";
	public static String outputFileRaw = "mql_validation_mql_raw.csv";
	
	public static int fileHandleIndicator = -1;
	public static int fileHandleLogic = -1;
	public static int fileHandleRaw = -1;
	
	public static long prevTime = 0;
	
	public static void init(){
		if(writeOutputFiles){
			fileHandleIndicator = MQLFileWriter.FileOpen(outputFileIndicator, FILE_CSV|FILE_WRITE|FILE_READ, ';');
			MQLFileWriter.FileWrite(fileHandleIndicator, "TIME","BID","ASK","LOW","HIGH","EMA3","EMA6","EMA9","EMA12","EMA15","EMA18","EMA21","EMA24","EMA27","EMA30","EMA33","EMA36","EMA39","EMA42","EMA45","EMA48","EMA51","EMA54","EMA57","EMA60","SMA3","SMA6","SMA9","SMA12","SMA15","SMA18","SMA21","SMA24","SMA27","SMA30","SMA33","SMA36","SMA39","SMA42","SMA45","SMA48","SMA51","SMA54","SMA57","SMA60");
			MQLFileWriter.FileSeek(fileHandleIndicator, 0, SEEK_END);

			fileHandleLogic = MQLFileWriter.FileOpen(outputFileLogic, FILE_CSV|FILE_WRITE|FILE_READ, ';');
			MQLFileWriter.FileWrite(fileHandleLogic, "TIME","LOGIC_BUY","LOGIC_SELL","SIGNAL","BALANCE");
			MQLFileWriter.FileSeek(fileHandleLogic, 0, SEEK_END);

			fileHandleRaw = MQLFileWriter.FileOpen(outputFileRaw, FILE_CSV|FILE_WRITE|FILE_READ, ';');
			MQLFileWriter.FileWrite(fileHandleRaw, "TIME","BID","ASK","LOW","HIGH");
			MQLFileWriter.FileSeek(fileHandleRaw, 0, SEEK_END);
		}
	}

	public static void deinit(){
		if(writeOutputFiles){
			MQLFileWriter.FileClose(fileHandleIndicator);
			MQLFileWriter.FileClose(fileHandleLogic);
			MQLFileWriter.FileClose(fileHandleRaw);
		}
	}	
	
	public static void start(){
		if(MQLIndicator.Time[0] != prevTime){
			prevTime = MQLIndicator.Time[0];
			
			globalIterationCounter++;
			// now we will update every indicator array
			shiftArray(INDICATOR_HIGH,MQLIndicator.Ask);
			shiftArray(INDICATOR_LOW,MQLIndicator.Bid);
			shiftArray(INDICATOR_HL_AVG, (MQLIndicator.Bid + MQLIndicator.Ask) / 2.0);

			if (fileHandleRaw > 0 && writeOutputFiles) {
				MQLFileWriter.FileWrite(fileHandleRaw, MQLIndicator.Time[0],MQLIndicator.Bid, MQLIndicator.Ask,MQLIndicator.Bid, MQLIndicator.Ask);
			}
			
			// we will start to push every indicator after we got 100 values, to make sure we have enough data to initialize all indicators
			// TODO eventeull die 100 auf einen kleineren Wert setzten (z.b. 50 vom ema50)
			if(globalIterationCounter == 60 && !execTestCase){
				shiftArray(INDICATOR_EMA3,myEMA(INDICATOR_HL_AVG,0,3,true));
				shiftArray(INDICATOR_EMA6,myEMA(INDICATOR_HL_AVG,0,5,true));
				shiftArray(INDICATOR_EMA9,myEMA(INDICATOR_HL_AVG,0,9,true));
				shiftArray(INDICATOR_EMA12,myEMA(INDICATOR_HL_AVG,0,12,true));
				shiftArray(INDICATOR_EMA15,myEMA(INDICATOR_HL_AVG,0,15,true));
				shiftArray(INDICATOR_EMA18,myEMA(INDICATOR_HL_AVG,0,18,true));
				shiftArray(INDICATOR_EMA21,myEMA(INDICATOR_HL_AVG,0,21,true));
				shiftArray(INDICATOR_EMA24,myEMA(INDICATOR_HL_AVG,0,24,true));
				shiftArray(INDICATOR_EMA27,myEMA(INDICATOR_HL_AVG,0,27,true));
				shiftArray(INDICATOR_EMA30,myEMA(INDICATOR_HL_AVG,0,30,true));
				shiftArray(INDICATOR_EMA33,myEMA(INDICATOR_HL_AVG,0,33,true));
				shiftArray(INDICATOR_EMA36,myEMA(INDICATOR_HL_AVG,0,36,true));
				shiftArray(INDICATOR_EMA39,myEMA(INDICATOR_HL_AVG,0,39,true));
				shiftArray(INDICATOR_EMA42,myEMA(INDICATOR_HL_AVG,0,42,true));
				shiftArray(INDICATOR_EMA45,myEMA(INDICATOR_HL_AVG,0,45,true));
				shiftArray(INDICATOR_EMA48,myEMA(INDICATOR_HL_AVG,0,48,true));
				shiftArray(INDICATOR_EMA51,myEMA(INDICATOR_HL_AVG,0,51,true));
				shiftArray(INDICATOR_EMA54,myEMA(INDICATOR_HL_AVG,0,54,true));
				shiftArray(INDICATOR_EMA57,myEMA(INDICATOR_HL_AVG,0,57,true));
				shiftArray(INDICATOR_EMA60,myEMA(INDICATOR_HL_AVG,0,60,true));
				
				shiftArray(INDICATOR_SMA3,mySMA(INDICATOR_HL_AVG,3));
				shiftArray(INDICATOR_SMA6,mySMA(INDICATOR_HL_AVG,5));
				shiftArray(INDICATOR_SMA9,mySMA(INDICATOR_HL_AVG,9));
				shiftArray(INDICATOR_SMA12,mySMA(INDICATOR_HL_AVG,12));
				shiftArray(INDICATOR_SMA15,mySMA(INDICATOR_HL_AVG,15));
				shiftArray(INDICATOR_SMA18,mySMA(INDICATOR_HL_AVG,18));
				shiftArray(INDICATOR_SMA21,mySMA(INDICATOR_HL_AVG,21));
				shiftArray(INDICATOR_SMA24,mySMA(INDICATOR_HL_AVG,24));
				shiftArray(INDICATOR_SMA27,mySMA(INDICATOR_HL_AVG,27));
				shiftArray(INDICATOR_SMA30,mySMA(INDICATOR_HL_AVG,30));
				shiftArray(INDICATOR_SMA33,mySMA(INDICATOR_HL_AVG,33));
				shiftArray(INDICATOR_SMA36,mySMA(INDICATOR_HL_AVG,36));
				shiftArray(INDICATOR_SMA39,mySMA(INDICATOR_HL_AVG,39));
				shiftArray(INDICATOR_SMA42,mySMA(INDICATOR_HL_AVG,42));
				shiftArray(INDICATOR_SMA45,mySMA(INDICATOR_HL_AVG,45));
				shiftArray(INDICATOR_SMA48,mySMA(INDICATOR_HL_AVG,48));
				shiftArray(INDICATOR_SMA51,mySMA(INDICATOR_HL_AVG,51));
				shiftArray(INDICATOR_SMA54,mySMA(INDICATOR_HL_AVG,54));
				shiftArray(INDICATOR_SMA57,mySMA(INDICATOR_HL_AVG,57));
				shiftArray(INDICATOR_SMA60,mySMA(INDICATOR_HL_AVG,60));

			}else if(globalIterationCounter > 60 && !execTestCase){
				shiftArray(INDICATOR_EMA3,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA3][0],3,true));
				shiftArray(INDICATOR_EMA6,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA6][0],5,true));
				shiftArray(INDICATOR_EMA9,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA9][0],9,true));
				shiftArray(INDICATOR_EMA12,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA12][0],12,true));
				shiftArray(INDICATOR_EMA15,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA15][0],15,true));
				shiftArray(INDICATOR_EMA18,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA18][0],18,true));
				shiftArray(INDICATOR_EMA21,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA21][0],21,true));
				shiftArray(INDICATOR_EMA24,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA24][0],24,true));
				shiftArray(INDICATOR_EMA27,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA27][0],27,true));
				shiftArray(INDICATOR_EMA30,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA30][0],30,true));
				shiftArray(INDICATOR_EMA33,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA33][0],33,true));
				shiftArray(INDICATOR_EMA36,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA36][0],36,true));
				shiftArray(INDICATOR_EMA39,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA39][0],39,true));
				shiftArray(INDICATOR_EMA42,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA42][0],42,true));
				shiftArray(INDICATOR_EMA45,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA45][0],45,true));
				shiftArray(INDICATOR_EMA48,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA48][0],48,true));
				shiftArray(INDICATOR_EMA51,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA51][0],51,true));
				shiftArray(INDICATOR_EMA54,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA54][0],54,true));
				shiftArray(INDICATOR_EMA57,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA57][0],57,true));
				shiftArray(INDICATOR_EMA60,myEMA(INDICATOR_HL_AVG,arrayData[INDICATOR_EMA60][0],60,true));
				
				shiftArray(INDICATOR_SMA3,mySMA(INDICATOR_HL_AVG,3));
				shiftArray(INDICATOR_SMA6,mySMA(INDICATOR_HL_AVG,5));
				shiftArray(INDICATOR_SMA9,mySMA(INDICATOR_HL_AVG,9));
				shiftArray(INDICATOR_SMA12,mySMA(INDICATOR_HL_AVG,12));
				shiftArray(INDICATOR_SMA15,mySMA(INDICATOR_HL_AVG,15));
				shiftArray(INDICATOR_SMA18,mySMA(INDICATOR_HL_AVG,18));
				shiftArray(INDICATOR_SMA21,mySMA(INDICATOR_HL_AVG,21));
				shiftArray(INDICATOR_SMA24,mySMA(INDICATOR_HL_AVG,24));
				shiftArray(INDICATOR_SMA27,mySMA(INDICATOR_HL_AVG,27));
				shiftArray(INDICATOR_SMA30,mySMA(INDICATOR_HL_AVG,30));
				shiftArray(INDICATOR_SMA33,mySMA(INDICATOR_HL_AVG,33));
				shiftArray(INDICATOR_SMA36,mySMA(INDICATOR_HL_AVG,36));
				shiftArray(INDICATOR_SMA39,mySMA(INDICATOR_HL_AVG,39));
				shiftArray(INDICATOR_SMA42,mySMA(INDICATOR_HL_AVG,42));
				shiftArray(INDICATOR_SMA45,mySMA(INDICATOR_HL_AVG,45));
				shiftArray(INDICATOR_SMA48,mySMA(INDICATOR_HL_AVG,48));
				shiftArray(INDICATOR_SMA51,mySMA(INDICATOR_HL_AVG,51));
				shiftArray(INDICATOR_SMA54,mySMA(INDICATOR_HL_AVG,54));
				shiftArray(INDICATOR_SMA57,mySMA(INDICATOR_HL_AVG,57));
				shiftArray(INDICATOR_SMA60,mySMA(INDICATOR_HL_AVG,60));

				if (fileHandleIndicator > 0 && writeOutputFiles) {
					MQLFileWriter.FileWrite(fileHandleIndicator, MQLIndicator.Time[0],MQLIndicator.Bid, MQLIndicator.Ask,MQLIndicator.Bid, MQLIndicator.Ask,arrayData[INDICATOR_EMA3][0],arrayData[INDICATOR_EMA6][0],arrayData[INDICATOR_EMA9][0],arrayData[INDICATOR_EMA12][0],arrayData[INDICATOR_EMA15][0],arrayData[INDICATOR_EMA18][0],arrayData[INDICATOR_EMA21][0],arrayData[INDICATOR_EMA24][0],arrayData[INDICATOR_EMA27][0],arrayData[INDICATOR_EMA30][0],arrayData[INDICATOR_EMA33][0],arrayData[INDICATOR_EMA36][0],arrayData[INDICATOR_EMA39][0],arrayData[INDICATOR_EMA42][0],arrayData[INDICATOR_EMA45][0],arrayData[INDICATOR_EMA48][0],arrayData[INDICATOR_EMA51][0],arrayData[INDICATOR_EMA54][0],arrayData[INDICATOR_EMA57][0],arrayData[INDICATOR_EMA60][0],arrayData[INDICATOR_SMA3][0],arrayData[INDICATOR_SMA6][0],arrayData[INDICATOR_SMA9][0],arrayData[INDICATOR_SMA12][0],arrayData[INDICATOR_SMA15][0],arrayData[INDICATOR_SMA18][0],arrayData[INDICATOR_SMA21][0],arrayData[INDICATOR_SMA24][0],arrayData[INDICATOR_SMA27][0],arrayData[INDICATOR_SMA30][0],arrayData[INDICATOR_SMA33][0],arrayData[INDICATOR_SMA36][0],arrayData[INDICATOR_SMA39][0],arrayData[INDICATOR_SMA42][0],arrayData[INDICATOR_SMA45][0],arrayData[INDICATOR_SMA48][0],arrayData[INDICATOR_SMA51][0],arrayData[INDICATOR_SMA54][0],arrayData[INDICATOR_SMA57][0],arrayData[INDICATOR_SMA60][0]);
				}

				//--------------------------------------------------
				// now we start trading

				invest = MQLIndicator.NormalizeDouble(money2Lot(MQLIndicator.AccountBalance()*0.1),2);

				boolean currentBuy = isBuy();
				boolean currentSell = isSell();

				if (currentSell) {
					if (currentBuy) {
						signalType = signalTypePrev;
					} else {
						signalType = ACTIVE_SIGNAL_SELL;
					}
				} else if (currentBuy) {
					signalType = ACTIVE_SIGNAL_BUY;
				} else{
					signalType = ACTIVE_SIGNAL_NONE;
				}

				if (fileHandleLogic > 0 && writeOutputFiles) {
					MQLFileWriter.FileWrite(fileHandleLogic, MQLIndicator.Time[0],currentBuy,currentSell,signalType,MQLIndicator.AccountBalance());
				}

				if (signalType != signalTypePrev) {
					if (signalTypePrev == ACTIVE_SIGNAL_BUY) {
						// close buy
						if (MQLIndicator.OrderSelect(ticket, SELECT_BY_TICKET) == true && MQLIndicator.OrdersTotal() > 0) {
							MQLIndicator.OrderClose(MQLIndicator.OrderTicket(), MQLIndicator.OrderLots(), MQLIndicator.Bid, 2, Green);
						}
					} else if (signalTypePrev == ACTIVE_SIGNAL_SELL) {
						// close sell
						if (MQLIndicator.OrderSelect(ticket, SELECT_BY_TICKET) == true && MQLIndicator.OrdersTotal() > 0) {
							MQLIndicator.OrderClose(MQLIndicator.OrderTicket(), MQLIndicator.OrderLots(), MQLIndicator.Ask, 2, Green);
						}
					}

					if (signalType == ACTIVE_SIGNAL_BUY) {
						// open buy
						ticket = MQLIndicator.OrderSend(MQLIndicator.Symbol(), OP_BUY, invest, MQLIndicator.NormalizeDouble(MQLIndicator.Ask, 5), 2, MQLIndicator.Ask - stopLoss, MQLIndicator.Ask + takeProfit, "My order #2", 16384, 0, Green);
					} else if (signalType == ACTIVE_SIGNAL_SELL) {
						// open sell
						ticket = MQLIndicator.OrderSend(MQLIndicator.Symbol(), OP_SELL, invest, MQLIndicator.NormalizeDouble(MQLIndicator.Bid, 5), 2, MQLIndicator.Bid + stopLoss, MQLIndicator.Bid - takeProfit, "My order #3", 16384, 0, Green);
					}
				}

				signalTypePrev = signalType;
			}
		}
	}

	public static boolean isBuy(){
		return false;
	}

	public static boolean isSell(){
		return false;
	}

	public static double money2Lot(double money){
		return (MQLIndicator.NormalizeDouble((money/LOT),2));
	}
	
	public static void shiftArray(final int indicator,final double value) {
		for(i=MAX_ARRAY_LEN-2;i>=0;i--){
			arrayData[indicator][i+1] = arrayData[indicator][i];
		}
		arrayData[indicator][0] = value;
	}

	public static boolean downTrend(final double valueA,final double valueB,final double valueC){
		boolean result = false;
		if(valueA < valueB && valueB < valueC){
			result = true;
		}
		return (result);
	}
	
	public static boolean upTrend(final double valueA,final double valueB,final double valueC){
		boolean result = false;
		if(valueA > valueB && valueB > valueC){
			result = true;
		}
		return (result);
	}
	
	public static boolean larger(final double valueA,final double valueB){
		boolean result = false;
		if(valueA > valueB){
			result = true;
		}
		return (result);
	}

	public static boolean largerEqual(final double valueA,final double valueB){
		boolean result = false;
		if(valueA >= valueB){
			result = true;
		}
		return (result);
	}

	public static boolean less(final double valueA,final double valueB){
		boolean result = false;
		if(valueA < valueB){
			result = true;
		}
		return (result);
	}

	public static boolean lessEqual(final double valueA,final double valueB){
		boolean result = false;
		if(valueA <= valueB){
			result = true;
		}
		return (result);
	}
	
	//--- custom indicators are here !---------------------------------------------------------------
	//------------------------------------------------------------------------------------------------
	//------------------------------------------------------------------------------------------------
	
	public static double mySMA(final int indicator,final double periodLen){
		double sum = 0.0;
		for(i=0;i<periodLen;i++){
			sum += arrayData[indicator][i];
		}
		return (sum / periodLen);
	}

	public static double myEMA(final int indicator,final double prevEMA,final int periodLen,final boolean doInit){
		double result;
		if(doInit){
			result = MQLScriptPrototype.mySMA(indicator, periodLen);
		}else{
			result = ((arrayData[indicator][0] - prevEMA) * (2.0 / (periodLen + 1.0))) + prevEMA;
		}
		return (result);
	}

}	//REMOVEME